package com.supplychainapi.utils;

import org.apache.commons.lang3.StringUtils;

import java.security.MessageDigest;
import java.util.*;

public class MD5Utils {
	
	private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

	/**
	 * 转换字节数组为16进制字串
	 * 
	 * @param b
	 *            字节数组
	 * @return 16进制字串
	 */
	public static String byteArrayToHexString(byte[] b) {
		StringBuilder resultSb = new StringBuilder();
		for (byte aB : b) {
			resultSb.append(byteToHexString(aB));
		}
		return resultSb.toString();
	}

	/**
	 * 转换byte到16进制
	 * 
	 * @param b
	 *            要转换的byte
	 * @return 16进制格式
	 */
	private static String byteToHexString(byte b) {
		int n = b;
		if (n < 0) {
			n = 256 + n;
		}
		int d1 = n / 16;
		int d2 = n % 16;
		return hexDigits[d1] + hexDigits[d2];
	}

	/**
	 * MD5编码
	 * 
	 * @param origin
	 *            原始字符串
	 * @return 经过MD5加密之后的结果
	 */
	public static String MD5Encode(String origin) {
		String resultString = null;
		try {
			resultString = origin;
			MessageDigest md = MessageDigest.getInstance("MD5");
			resultString = byteArrayToHexString(md.digest(resultString.getBytes("UTF-8")));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultString;
	}

	public static String getSign(Map<String, String> map, String posKey) {
		ArrayList<String> list = new ArrayList<String>();
		for (Map.Entry<String, String> entry : map.entrySet()) {
			if (!entry.getValue().equals("") && !entry.getKey().equals("Signature")) {
				list.add(entry.getKey() + "=" + entry.getValue() + "&");
			}
		}
		int size = list.size();
		String[] arrayToSort = list.toArray(new String[size]);
		Arrays.sort(arrayToSort);
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < size; i++) {
			sb.append(arrayToSort[i]);
		}
		String result = sb.toString();
		result += "key=" + posKey; // key是双方约定的加密秘钥
		result = MD5Utils.MD5Encode(result).toUpperCase();
		
		return result;
	}

	/**
	 * 支付签名
	 */
	public static String getFinalSign(Map<String, String> params, String payKey) {
		String sign = "";
		Collection<String> keyset = params.keySet();
		List<String> list = new ArrayList<String>(keyset);
		Collections.sort(list);
		for (int i = 0; i < list.size(); i++) {
			sign = sign + list.get(i) + "=" + params.get(list.get(i)) + "&";
		}
		String mdKey = payKey;
		String tmpSign1 = MD5Encode(sign + mdKey);
		String tmpSign2 = tmpSign1.substring(0, tmpSign1.length() - 1) + "w";
		String finalSign = MD5Encode(tmpSign2);
		return finalSign;
	}
	
	/**
	 * 支付签名 
	 */
	public static String getNotifySign(Map<String, String> params, String payKey) {
		String sign = "";
		Collection<String> keyset = params.keySet();
		List<String> list = new ArrayList<String>(keyset);
		Collections.sort(list);
		for (int i = 0; i < list.size(); i++) {
			if (StringUtils.isNotBlank(list.get(i)) && !StringUtils.equals("sign", list.get(i).toString())) {
				sign = sign + list.get(i) + "=" + params.get(list.get(i)) + "&";
			}
		}
		String mdKey = payKey;
		String tmpSign1 = MD5Encode(sign + mdKey);
		String tmpSign2 = tmpSign1.substring(0, tmpSign1.length() - 1) + "b";
		String finalSign = MD5Encode(tmpSign2);
		return finalSign;
	}

	public static void main(String[] args) {
		//ext_receipt=100, pay_price=100, sign=1b82410971ce4e96188488a125e2a9bf, thr_discount=0, pay_account=oApmQt1Q--aGS_QkkJJsF7Zf1zr8, pay_shopid=0, 
		//notify_type=1, pay_status=1, platform_merchant_discount=0, pay_order=359797a6c43a40a19569c10a3b1387, 
		//pay_shop_uuid=30fe5e8a-b237-4262-99b1-4e2deb5775c8, pay_order1=4003752001201709070684562408, pay_paytime=2017-09-07 10:25:07, pay_class=1, pay_price1=100, pay_id=1029005, pay_sourceid=102, platform_total_discount=0
		Map<String, String> map = new HashMap<String, String>();
		map.put("ext_receipt", "0");
		map.put("pay_price", "100");
		map.put("sign", "5a2330084154a8bbd1543ec723095cfc");
		map.put("thr_discount", "0");
		map.put("pay_account", "oApmQt1Q--aGS_QkkJJsF7Zf1zr8");
		map.put("pay_shopid", "0");
		map.put("notify_type", "1");
		map.put("pay_status", "1");
		map.put("platform_merchant_discount", "0");
		map.put("pay_order", "359797a6c43a40a1956330a3337");
		map.put("pay_shop_uuid", "30fe5e8a-b237-4262-99b1-4e2deb5775c8");
		map.put("pay_order1", "4003752001201709070685491424");
		map.put("pay_paytime", "2017-09-07 10:46:50");
		map.put("pay_class", "1");
		map.put("pay_price1", "100");
		map.put("pay_id", "1029008");
		map.put("pay_sourceid", "102");
		map.put("platform_total_discount", "0");
		// ext_receipt=0&notify_type=1&pay_account=oApmQt1Q--aGS_QkkJJsF7Zf1zr8&pay_class=1&pay_id=1029008&pay_order=359797a6c43a40a1956330a3337&pay_order1=4003752001201709070685491424&pay_paytime=2017-09-07 10:46:50&pay_price=100&pay_price1=100&pay_shop_uuid=30fe5e8a-b237-4262-99b1-4e2deb5775c8&pay_shopid=0&pay_sourceid=102&pay_status=1&platform_merchant_discount=0&platform_total_discount=0&thr_discount=0&
		// ext_receipt=0&notify_type=1&pay_account=oApmQt1Q--aGS_QkkJJsF7Zf1zr8&pay_class=1&pay_id=1029008&pay_order=359797a6c43a40a1956330a3337&pay_order1=4003752001201709070685491424&pay_paytime=2017-09-07 10:46:50&pay_price=100&pay_price1=100&pay_shop_uuid=30fe5e8a-b237-4262-99b1-4e2deb5775c8&pay_shopid=0&pay_sourceid=102&pay_status=1&platform_merchant_discount=0&platform_total_discount=0&thr_discount=0&



		System.out.println(MD5Utils.getNotifySign(map,"13d2b57591d5f87992fce423b9503a14"));
//		
//		String str = "{\"fsShopID\":1033,\"pay_order\":\"S20170816000008\",\"pay_name\":\"收银条码支付\",\"pay_price\":0.01,\"pay_class\":1,\"pay_micro\":\"130126845385324927\",\"pay_discountable\":0,\"fsShopGUID\":\"407024501f5f11e7887100163e121a7d\",\"fsCreateUserId\":\"001\",\"fsCreateUserName\":\"001\",\"sign\":\"9608b7fc016739a1f52287604ad9c76f\"}";
//	
//		JSONObject jsonObject = JSONObject.parseObject(str);
//		Set<String> keyset = jsonObject.keySet();
//		Map<String, String> param_map = new HashMap<String, String>();
//		Iterator<String> it = keyset.iterator();
//		while (it.hasNext()) {
//			String json_key = it.next();
//			Object json_value = jsonObject.get(json_key);
//			param_map.put(json_key, json_value.toString());
//		}
//		System.out.println(param_map);
//		String sign = getFinalSign(param_map);
//		System.out.println(sign);
	}

}
